home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / NR4TIMER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-29  |  4.6 KB  |  188 lines

  1. /* net/rom level 4 (transport) protocol timer management.
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5.  
  6. #include "global.h"
  7. #ifdef NETROM
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "netrom.h"
  12.  
  13. #if !defined(_lint)
  14. static char rcsid[] OPTIONAL = "$Id: nr4timer.c,v 1.8 1996/08/29 12:11:16 root Exp root $";
  15. #endif
  16.  
  17. #undef NR4DEBUG
  18.  
  19. unsigned Nr_timertype = 0;    /* default to binary exponential */
  20.  
  21.  
  22. /* The ACK timer has expired without any data becoming available.
  23.  * Go ahead and send an ACK.
  24.  */
  25.  
  26. void
  27. nr4ackit (void *p)
  28. {
  29. struct nr4cb *cb = (struct nr4cb *) p;
  30. struct nr4hdr rhdr;
  31.  
  32. #ifdef NR4DEBUG
  33.     printf ("ACKIT called.\n");
  34. #endif
  35.  
  36.     stop_timer (&cb->tack);    /* fixed N1BEE 920811 */
  37.     if (cb->qfull)        /* Are we choked? */
  38.         rhdr.opcode = NR4OPACK | NR4CHOKE;
  39.     else
  40.         rhdr.opcode = NR4OPACK;
  41.     rhdr.yourindex = uchar (cb->yournum);
  42.     rhdr.yourid = uchar (cb->yourid);
  43.     rhdr.u.ack.rxseq = cb->rxpected;
  44.  
  45.     nr4sframe (cb->remote.node, &rhdr, NULLBUF);
  46. }
  47.  
  48.  
  49. /* Called when one of the transmit timers has expired */
  50.  
  51. void
  52. nr4txtimeout (void *p)
  53. {
  54. struct nr4cb *cb = (struct nr4cb *) p;
  55. unsigned seq;
  56. struct nr4txbuf *t;
  57.  
  58.     /* Sanity check */
  59.     if (cb->state != NR4STCON)
  60.         return;
  61.  
  62.     /* Scan through the send window looking for expired timers */
  63.  
  64.     for (seq = cb->ackxpected;
  65.          nr4between ((unsigned) cb->ackxpected, seq, (unsigned) cb->nextosend);
  66.          seq = (seq + 1) & NR4SEQMASK) {
  67.  
  68.         t = &cb->txbufs[seq % cb->window];
  69.  
  70.         if (t->tretry.state == TIMER_EXPIRE) {
  71.             t->tretry.state = TIMER_STOP;    /* So we don't do it again */
  72.             /* This thing above fails because the timer code
  73.                itself does the reverse, changing TIMER_STOP to
  74.                TIMER_EXPIRE.  What we really want to do here
  75.                is properly restart the timer.  -- N1BEE */
  76.             /* start_timer(&(t->tretry)); */
  77.  
  78.             if (t->retries == Nr4retries) {
  79.                 cb->dreason = NR4RTIMEOUT;
  80.                 nr4state (cb, NR4STDISC);
  81.             }
  82.             t->retries++;
  83.  
  84.             /* We keep track of the highest retry count in the window. */
  85.             /* If packet times out and its new retry count exceeds the */
  86.             /* max, we update the max and bump the backoff level.  This */
  87.             /* expedient is to avoid bumping the backoff level for every */
  88.             /* expiration, since with more than one timer we would back */
  89.             /* off way too fast (and at a rate dependent on the window */
  90.             /* size! */
  91.  
  92.             if (t->retries > cb->txmax) {
  93.                 cb->blevel++;
  94.                 cb->txmax = t->retries;    /* update the max */
  95.             }
  96.             nr4sbuf (cb, seq);    /* Resend buffer */
  97.         }
  98.     }
  99.  
  100. }
  101.  
  102.  
  103. /* Connect/disconnect acknowledgement timeout */
  104.  
  105. void
  106. nr4cdtimeout (void *p)
  107. {
  108. struct nr4cb *cb = (struct nr4cb *) p;
  109. struct nr4hdr hdr;
  110.  
  111.     switch (cb->state) {
  112.         case NR4STCPEND:
  113.             if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  114.                 cb->dreason = NR4RTIMEOUT;
  115.                 nr4state (cb, NR4STDISC);    /* Give it up */
  116.             } else {
  117.                 /* Set up header */
  118.  
  119.                 hdr.opcode = NR4OPCONRQ;
  120.                 hdr.u.conreq.myindex = uchar (cb->mynum);
  121.                 hdr.u.conreq.myid = uchar (cb->myid);
  122.                 hdr.u.conreq.window = uchar (Nr4window);
  123.                 memcpy (hdr.u.conreq.user, cb->local.user, AXALEN);
  124.                 memcpy (hdr.u.conreq.node, cb->local.node, AXALEN);
  125.  
  126.                 /* Bump tries counter and backoff level, and restart timer */
  127.                 /* We use a linear or binary exponential backoff. */
  128.  
  129.                 cb->cdtries++;
  130.                 cb->blevel++;
  131.  
  132.                 if (Nr_timertype)
  133.                     /* linear */
  134.                     set_timer (&cb->tcd, dur_timer (&cb->tcd) + cb->srtt);
  135.                 else
  136.                     /* exponential */
  137.                     set_timer (&cb->tcd, dur_timer (&cb->tcd) * 2);
  138.  
  139.                 start_timer (&cb->tcd);
  140.  
  141.                 /* Send connect request packet */
  142.  
  143.                 nr4sframe (cb->remote.node, &hdr, NULLBUF);
  144.             }
  145.             break;
  146.  
  147.         case NR4STDPEND:
  148.             if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  149.                 cb->dreason = NR4RTIMEOUT;
  150.                 nr4state (cb, NR4STDISC);    /* Give it up */
  151.             } else {
  152.                 /* Format header */
  153.  
  154.                 hdr.opcode = NR4OPDISRQ;
  155.                 hdr.yourindex = uchar (cb->yournum);
  156.                 hdr.yourid = uchar (cb->yourid);
  157.  
  158.                 /* Bump retry count and start timer */
  159.                 /* We don't really need to be fancy here, since we */
  160.                 /* should have a good idea of the round trip time by now. */
  161.  
  162.                 cb->cdtries++;
  163.                 start_timer (&cb->tcd);
  164.  
  165.                 /* Send disconnect request packet */
  166.  
  167.                 nr4sframe (cb->remote.node, &hdr, NULLBUF);
  168.             }
  169.             break;
  170.         default:
  171.             break;
  172.     }
  173. }
  174.  
  175.  
  176. /* The choke timer has expired.  Unchoke and kick. */
  177.  
  178. void
  179. nr4unchoke (void *p)
  180. {
  181. struct nr4cb *cb = (struct nr4cb *) p;
  182.  
  183.     cb->choked = 0;
  184.     (void) nr4output (cb);
  185. }
  186.  
  187. #endif /* NETROM */
  188.